﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Browis.Package;
using System.Data;


namespace Browis.Cds.Plugin
{
     public class GetImportDataFile
    {
         public string GetImportFile(DataCommand command, string sRoot,string sFileName)
         {
             string sRtn = Path.Combine(sRoot,string.Format("{0}.dat",sFileName));

             if (command.DataReader == null)
             {
                 sRtn = null;
             }
             else
             {
                 File.Delete(sRtn);
                 using (FileStream file = new FileStream(sRtn, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
                 {
                     byte[] bLen = new byte[DataCommand.GetSizeOfType("uint")];
                     //byte[] bFmintor = System.Text.Encoding.UTF8.GetBytes("\0\0\0\0,");
                     //byte[] bRmintor = System.Text.Encoding.UTF8.GetBytes("\0\0\0\0\n");

                     while (command.DataReader.Position < command.DataReader.Length)
                     {
                         foreach (CommandValue cmdValue in command.CommandValues)
                         {
                             //如果是可空列，且标记为空，跳过
                             if (cmdValue.AllowNull)
                             {
                                 if (command.DataReader.ReadByte() == 1)
                                 {
                                     if (command.CommandValues.IndexOf(cmdValue) < command.CommandValues.Count - 1)
                                     {
                                         file.WriteByte(0);
                                         file.WriteByte(0);
                                         file.WriteByte(0);
                                         file.WriteByte(0);
                                         file.WriteByte(BitConverter.GetBytes(',')[0]);
                                     }
                                     continue;
                                 }
                             }
                             //获取本数据的长度
                             uint iLength = cmdValue.Length;
                             if (DataCommand.IsFixedLengthType(cmdValue.Type))
                             {
                                 iLength = DataCommand.GetSizeOfType(cmdValue.Type);
                             }
                             else if (iLength == 0)
                             {
                                 command.DataReader.Read(bLen, 0, bLen.Length);
                                 iLength = BitConverter.ToUInt32(bLen, 0);
                             }
                             byte[] bValue = null;
                             //如果数据长度在整形数字范围内
                             if (iLength <= int.MaxValue)
                             {
                                 bValue = new byte[iLength];
                                 command.DataReader.Read(bValue, 0, (int)iLength);
                                 if (cmdValue.Type.ToLower() == "byte[]")
                                 {
                                     StringBuilder sHex = new StringBuilder();
                                     for (int i = 0; i < bValue.Length; i++)
                                     {
                                         sHex.Append(bValue[i].ToString("X2"));
                                     }
                                     byte[] bHexValue = System.Text.Encoding.GetEncoding("gb2312").GetBytes(sHex.ToString());
                                     //新生成的内容大小，是原内容的两倍
                                     if (bHexValue.Length <= int.MaxValue)
                                     {
                                         bValue = bHexValue;
                                     }
                                     else
                                     {
                                         file.Write(bHexValue, 0, int.MaxValue);
                                         bValue = new byte[bHexValue.Length - int.MaxValue];
                                         Array.Copy(bHexValue, int.MaxValue, bValue, 0, bValue.Length);
                                     }
                                 }
                                 else if (cmdValue.Type.ToLower() == "datetime")
                                 {
                                     bValue = System.Text.Encoding.GetEncoding("gb2312").GetBytes(((DateTime)DataCommand.ConvertBytesToObj(bValue, cmdValue.Type)).ToString("yyyy-MM-dd HH:mm:ss.fff"));
                                 }
                                 else if (cmdValue.Type.ToLower() != "string")
                                 {
                                     string sObj = DataCommand.ConvertBytesToObj(bValue, cmdValue.Type).ToString();
                                     bValue = System.Text.Encoding.GetEncoding("gb2312").GetBytes(sObj);
                                 }
                                 else
                                 {
                                     bValue = System.Text.Encoding.Convert(System.Text.Encoding.UTF8, System.Text.Encoding.GetEncoding("gb2312"), bValue);
                                 }
                                 file.Write(bValue, 0, bValue.Length);
                             }
                             //数据超出整形数据范围
                             else
                             {
                                 bValue = new byte[int.MaxValue];
                                 while (true)
                                 {
                                     int iCount = command.DataReader.Read(bValue, 0, int.MaxValue);
                                     //如果是字节数组，转换为十六进制
                                     if (cmdValue.Type.ToLower() == "byte[]")
                                     {
                                         StringBuilder sHex = new StringBuilder();
                                         for (int i = 0; i < iCount; i++)
                                         {
                                             sHex.Append(bValue[i].ToString("X2"));
                                         }
                                         byte[] bHexValue = System.Text.Encoding.GetEncoding("gb2312").GetBytes(sHex.ToString());
                                         if (bHexValue.Length <= int.MaxValue)
                                         {
                                             bValue = bHexValue;
                                         }
                                         else
                                         {
                                             file.Write(bHexValue, 0, int.MaxValue);
                                             bValue = new byte[bHexValue.Length - int.MaxValue];
                                             Array.Copy(bHexValue, int.MaxValue, bValue, 0, bValue.Length);
                                         }
                                         file.Write(bValue, 0, bValue.Length);
                                     }
                                     //其他（字符类型）直接输出。（注意：可能输出的是UTF-8编码文字）
                                     else
                                     {
                                         file.Write(bValue, 0, iCount);
                                     }

                                     if (iCount < int.MaxValue)
                                     {
                                         break;
                                     }
                                 }
                             }
                             if (command.CommandValues.IndexOf(cmdValue) < command.CommandValues.Count - 1)
                             {
                                 //以4个\0加逗号为结束标记
                                 file.WriteByte(0);
                                 file.WriteByte(0);
                                 file.WriteByte(0);
                                 file.WriteByte(0);
                                 file.WriteByte(BitConverter.GetBytes(',')[0]);
                             }
                         }
                         //以4个\0加换行为结束标记
                         file.WriteByte(0);
                         file.WriteByte(0);
                         file.WriteByte(0);
                         file.WriteByte(0);
                         file.WriteByte(BitConverter.GetBytes('\r')[0]);
                         file.WriteByte(BitConverter.GetBytes('\n')[0]);
                         
                     }
                 }
             }
             return sRtn;
         }

         public DataTable GetDataTable(DataCommand command)
         {
             DataTable dtRtn = new DataTable();


             if (command.DataReader == null)
             {
                 dtRtn = null;
             }
             else
             {
                 byte[] bLen = new byte[DataCommand.GetSizeOfType("uint")];
                 //生成列
                 foreach (CommandValue cmdValue in command.CommandValues)
                 {
                     DataColumn colTmp = new DataColumn(cmdValue.ID, GetTypeFromTypeString(cmdValue.Type));
                     //colTmp.DataType = GetTypeFromTypeString(cmdValue.Type);
                     dtRtn.Columns.Add(colTmp);
                 }

                 DataRow dtRow = null;
                 long startPos = command.DataReader.Position;
                 while (command.DataReader.Position < command.DataReader.Length)
                 {
                     dtRow = dtRtn.NewRow();
                     foreach (CommandValue cmdValue in command.CommandValues)
                     {
                         //如果是可空列，且标记为空，跳过
                         if (cmdValue.AllowNull)
                         {
                             if (command.DataReader.ReadByte() == 1)
                             {
                                 dtRow[cmdValue.ID] = DBNull.Value;
                                 continue;
                             }
                         }
                         //获取本数据的长度
                         uint iLength = cmdValue.Length;
                         if (DataCommand.IsFixedLengthType(cmdValue.Type))
                         {
                             iLength = DataCommand.GetSizeOfType(cmdValue.Type);
                         }
                         else if (iLength == 0)
                         {
                             command.DataReader.Read(bLen, 0, bLen.Length);
                             iLength = BitConverter.ToUInt32(bLen, 0);
                         }
                         byte[] bValue = new byte[iLength];

                         //如果数据长度在整形数字范围内
                         if (iLength <= int.MaxValue)
                         {
                             command.DataReader.Read(bValue, 0, (int)iLength);
                         }
                         //数据超出整形数据范围
                         else
                         {
                             int iCount = 0;
                             while (true)
                             {
                                 iCount = command.DataReader.Read(bValue, iCount, int.MaxValue);
                                 if (iCount < int.MaxValue)
                                 {
                                     break;
                                 }
                             }
                         }
                         if (cmdValue.Type.ToLower() == "byte[]")
                         {
                             dtRow[cmdValue.ID] = bValue;
                         }
                         else
                         {
                             dtRow[cmdValue.ID] = DataCommand.ConvertBytesToObj(bValue, cmdValue.Type);
                         }
                     }
                     dtRtn.Rows.Add(dtRow);
                     //判断读取字节数据是否已经超过50M，超过的，终止循环，将现有数据组成的DataTable返回
                     if (command.DataReader.Position - startPos >= 52428800)
                     {
                         break;
                     }
                 }
             }
             return dtRtn;
         }

         private Type GetTypeFromTypeString(string sType)
         {
             switch (sType.Trim().ToLower())
             {
                 case "bool":
                     return typeof(bool);
                 case "int":
                     return typeof(int);
                 case "uint":
                     return typeof(uint);
                 case "long":
                     return typeof(long);
                 case "ulong":
                     return typeof(ulong);
                 case "short":
                     return typeof(short);
                 case "ushort":
                     return typeof(ushort);
                 case "float":
                     return typeof(float);
                 case "double":
                     return typeof(double);
                 case "char":
                     return typeof(char);
                 case "decimal":
                     return typeof(decimal);
                 case "byte":
                     return typeof(byte);
                 case "datetime":
                     return typeof(DateTime);
                 case "guid":
                     return typeof(Guid);
                 case "string":
                     return typeof(string);
                 case "byte[]":
                     return typeof(Byte[]);
                 default:
                     throw new Exception("指示的列有未知的类型：" + sType);
             }

         }
    }
}
